package com.yida.gwj.config.service.impl;

import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import java.util.Map;
import java.util.function.Function;
import java.util.stream.Collectors;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import com.alibaba.fastjson2.JSONObject;
import com.yida.common.core.exception.ServiceException;
import com.yida.common.core.utils.DateUtils;
import com.yida.common.core.utils.StringUtils;
import com.yida.common.security.utils.SecurityUtils;
import com.yida.gwj.api.domain.GwjConfStep;
import com.yida.gwj.api.domain.GwjConfStepConfig;
import com.yida.gwj.config.domain.dto.GwjConfStepConfigDTO;
import com.yida.gwj.config.domain.dto.GwjConfStepDTO;
import com.yida.gwj.config.domain.request.GwjConfStepConfigRequest;
import com.yida.gwj.config.domain.request.GwjConfStepRequest;
import com.yida.gwj.config.mapper.GwjConfStepConfigMapper;
import com.yida.gwj.config.mapper.GwjConfStepMapper;
import com.yida.gwj.config.service.IGwjConfStepService;

import cn.hutool.core.collection.CollectionUtil;

/**
 * 业务步骤Service业务层处理
 *
 * @author lqq
 * @date 2022-12-14
 */
@Service
public class GwjConfStepServiceImpl implements IGwjConfStepService {

    @Autowired
    private GwjConfStepMapper gcStepMapper;

    @Autowired
    private GwjConfStepConfigMapper gcStepConfigMapper;

    /**
     * 查询业务步骤列表
     *
     * @param gcStep 业务步骤
     * @return 业务步骤
     */
    @Override
    public List<GwjConfStep> selectGwjConfStepList(GwjConfStep gcStep) {
        gcStep.setDelFlag("0");
        return gcStepMapper.selectGwjConfStepList(gcStep);
    }

    /**
     * 根据状态查询业务步骤列表
     *
     * @param status 状态
     * @return 业务步骤集合
     */
    @Override
    public List<GwjConfStep> selectGwjConfStepListByStatus(String status) {
        GwjConfStep gcStep = new GwjConfStep();
        gcStep.setStatus(status);
        return gcStepMapper.selectGwjConfStepList(gcStep);
    }

    /**
     * 查询业务步骤
     *
     * @param stepId 业务步骤主键
     * @return 业务步骤
     */
    @Override
    public GwjConfStep selectByGwjConfStepId(Long stepId) {
        GwjConfStep gcStep = gcStepMapper.selectByGwjConfStepId(stepId);
        if (StringUtils.isNotNull(gcStep)) {
            // 查询所绑定的功能
            List<GwjConfStepConfig> gcStepConfigs = gcStepConfigMapper.selectGwjConfStepConfigListByStepId(stepId);
            if (StringUtils.isNotEmpty(gcStepConfigs)) {
                gcStep.setConfigs(gcStepConfigs.stream().map(GwjConfStepConfig::getConfigId).toArray(Long[]::new));
            }
        }
        return gcStep;
    }

    @Override
    public void insertGwjConfStep(GwjConfStep gcStep) {
        // if (StringUtils.isNotNull(gcStepMapper.selectByGwjConfStepName(gcStep.getName()))) {
        // throw new ServiceException("[save]名称已存在");
        // }
        gcStep.setCreateTime(DateUtils.getNowDate());
        gcStep.setCreateBy(SecurityUtils.getLoginUser().getSysUser().getRealName());
        gcStepMapper.insertGwjConfStep(gcStep);
        // 插入配置信息
        List<GwjConfStepConfig> gcStepConfigs = convertGwjConfStepConfigList(gcStep.getStepId(), gcStep.getConfigs());
        if (gcStepConfigs.size() > 0) {
            gcStepConfigMapper.batchGwjConfStepConfig(gcStepConfigs);
        }
    }

    @Override
    public void updateGwjConfStep(GwjConfStep gcStep) {
        // GwjConfStep temp = gcStepMapper.selectByGwjConfStepName(gcStep.getName());
        // if (StringUtils.isNotNull(temp) && !temp.getStepId().equals(gcStep.getStepId())) {
        // throw new ServiceException("[update]流程名称已存在");
        // }
        gcStep.setUpdateTime(DateUtils.getNowDate());
        gcStep.setUpdateBy(SecurityUtils.getLoginUser().getSysUser().getRealName());
        gcStepMapper.updateGwjConfStep(gcStep);
        Long stepId = gcStep.getStepId();
        // 删除原有步骤配置
        gcStepConfigMapper.deleteGwjConfStepConfigByStepId(stepId);
        // 插入配置信息
        List<GwjConfStepConfig> gcStepConfigs = convertGwjConfStepConfigList(stepId, gcStep.getConfigs());
        if (gcStepConfigs.size() > 0) {
            gcStepConfigMapper.batchGwjConfStepConfig(gcStepConfigs);
        }
    }

    /**
     * 根据配置项进行集合转换
     *
     * @param stepId 步骤ID
     * @param configs 配置组
     * @return /
     */
    private List<GwjConfStepConfig> convertGwjConfStepConfigList(Long stepId, Long[] configs) {
        List<GwjConfStepConfig> gcStepConfigs = new ArrayList<GwjConfStepConfig>();
        for (Long configId : configs) {
            GwjConfStepConfig gcStepConfig = new GwjConfStepConfig();
            gcStepConfig.setStepId(stepId);
            gcStepConfig.setConfigId(configId);
        }
        return gcStepConfigs;
    }

    /**
     * 批量删除业务步骤
     *
     * @param stepIds 需要删除的业务步骤主键
     * @return 结果
     */
    @Override
    public int deleteByGwjConfStepIds(Long[] stepIds) {
        List<GwjConfStep> list = Arrays.stream(stepIds).map(id -> {
            GwjConfStep temp = new GwjConfStep();
            temp.setDelFlag("2");
            temp.setUpdateTime(DateUtils.getNowDate());
            temp.setUpdateBy(SecurityUtils.getLoginUser().getSysUser().getRealName());
            temp.setStepId(id);
            return temp;
        }).collect(Collectors.toList());
        return gcStepMapper.updateBatchGwjConfStep(list);
    }

    /**
     * 根据业务标识查询步骤ID列表
     *
     * @param flagId 业务标识ID
     * @return 业务标识集合
     */
    @Override
    public List<GwjConfStep> selectGwjConfStepListByFlagId(Integer flagId) {
        // return gcStepMapper.selectGwjConfStepIdListByBizFlagId(flagId);
        List<GwjConfStep> gwjConfStepList = gcStepMapper.selectGwjConfStepIdListByBizFlagId(flagId);
        if (StringUtils.isEmpty(gwjConfStepList)) {
            throw new ServiceException("未能获取到对应业务标识ID配置信息，请确认配置后操作！");
        }
        return gwjConfStepList;
    }

    /**
     * 查询下一个步骤
     *
     * @param flagId 业务标识ID
     * @param currentStep 当前步骤
     * @return 返回null为当前步骤已经是最后一步
     */
    @Override
    public GwjConfStep selectNextGwjConfStepByFlagId(Integer flagId, Long currentStep) {
        List<GwjConfStep> steps = selectGwjConfStepListByFlagId(flagId);
        for (int i = 0; i < steps.size(); i++) {
            if (steps.get(i).getStepId().equals(currentStep)) {
                // 当前步骤是最后一步
                if (i == steps.size() - 1) {
                    return null;
                }
                return steps.get(i + 1);
            }
        }
        return null;
    }

    /**
     * 查询上一个步骤
     *
     * @param flagId 业务标识ID
     * @param currentStep 当前步骤
     * @return 返回null为当前步骤已经是第一步
     */
    @Override
    public GwjConfStep selectPreviousGwjConfStepByFlagId(Integer flagId, Long currentStep) {
        List<GwjConfStep> steps = selectGwjConfStepListByFlagId(flagId);
        for (int i = 0; i < steps.size() - 1; i++) {
            if (steps.get(i).getStepId().equals(currentStep)) {
                // 当前步骤是第一步返回空
                if (i == 0) {
                    return null;
                }
                return steps.get(i - 1);
            }
        }
        return null;
    }

    // -----------------------------------------------------20230224新增功能

    /**
     * 根据步骤ID查询详情
     *
     * @param stepId 步骤ID
     * @return
     */
    @Override
    public GwjConfStepDTO queryGwjConfStepByGwjConfStepId(Long stepId) {
        return gcStepMapper.selectGwjConfStepByGwjConfStepId(stepId);
    }

    /**
     * 根据步骤ID获取已配置信息
     *
     * @param gwjConfStepId 步骤ID
     * @return
     */
    @Override
    public List<GwjConfStepConfigDTO> selectGwjConfStepConfigListByGwjConfStepId(Long gwjConfStepId) {
        return gcStepConfigMapper.selectGwjConfStepConfigListByGwjConfStepId(gwjConfStepId);
    }

    /**
     * 20230227
     * <p>
     * hmh
     * <p>
     * 新增业务步骤
     *
     * @param gwjConfStepRequest
     * @return
     */
    @Override
    public int insertGwjConfStep(GwjConfStepRequest gwjConfStepRequest) {
        GwjConfStep gcs = new GwjConfStep();
        // gcs.setStepId(stepId);
        gcs.setName(gwjConfStepRequest.getStepName());
        gcs.setRemark(gwjConfStepRequest.getRemark());
        gcs.setCreateTime(DateUtils.getNowDate());
        gcs.setCreateBy(SecurityUtils.getLoginUser().getSysUser().getRealName());
        gcs.setStatus("0");
        return gcStepMapper.insertGwjConfStep(gcs);
    }

    /**
     * 20230227
     * <p>
     * hmh
     * <p>
     * 修改业务步骤
     *
     * @param gwjConfStepRequest
     * @return
     */
    @Override
    public int updateGwjConfStep(GwjConfStepRequest gwjConfStepRequest) {
        GwjConfStep gcs = new GwjConfStep();
        gcs.setStepId(gwjConfStepRequest.getStepId());
        gcs.setName(gwjConfStepRequest.getStepName());
        gcs.setRemark(gwjConfStepRequest.getRemark());
        gcs.setStatus(gwjConfStepRequest.getStatus());
        gcs.setUpdateTime(DateUtils.getNowDate());
        gcs.setUpdateBy(SecurityUtils.getLoginUser().getSysUser().getRealName());
        return gcStepMapper.updateGwjConfStep(gcs);
    }

    /**
     * 20230224
     * <p>
     * hmh
     * <p>
     * 新增业务步骤配置
     *
     * @param gwjConfStepRequest 业务步骤配置请求类
     * @return
     */
    @Override
    public int batchInsertGwjConfStepConfigRequest(GwjConfStepConfigRequest gwjConfStepConfigRequest) {
        List<GwjConfStepConfig> list = gwjConfStepConfigRequest.getGwjConfStepConfigList();
        if (list == null || list.size() == 0) {
            throw new ServiceException("请至少勾选一项配置！");
        }
        Long stepId = gwjConfStepConfigRequest.getStepId();
        if (stepId > 0) {
            // 检查stepId是否存在
            if (gcStepMapper.selectByGwjConfStepId(stepId) == null) {
                throw new ServiceException("未获取到对应步骤信息！");
            }
            gcStepConfigMapper.deleteGwjConfStepConfigByStepId(stepId);
        }
        return gcStepConfigMapper.batchGwjConfStepConfigRequest(list);
    }

    // @Override
    // public int batchUpdateGwjConfStepConfigRequest(List<GwjConfStepConfigRequest> gGwjConfStepConfigRequestList) {
    // // 获取对应步骤ID
    // Long stepId = gGwjConfStepConfigRequestList.get(0).getStepId();
    // // 删除指定配置
    // int num = gcStepConfigMapper.deleteGwjConfStepConfigByStepId(stepId);
    // if (num > 0) {
    // // 批量新增对应数据
    // return batchInsertGwjConfStepConfigRequest(gGwjConfStepConfigRequestList);
    // } else {
    // throw new ServiceException("配置修改失败！");
    // }
    // }

    // -----------------------------------------------------20230224新增功能

    /**
     * 20230418 wkz 获取最后一个步骤
     *
     * @param flagId 标识id
     * @return {@link GwjConfStepDTO}
     */
    @Override
    public GwjConfStep getFinalStep(Integer flagId) {
        List<GwjConfStep> gwjConfSteps = gcStepMapper.selectGwjConfStepIdListByBizFlagId(flagId);
        if (CollectionUtil.isEmpty(gwjConfSteps)) {
            return null;
        }
        return gwjConfSteps.get(gwjConfSteps.size() - 1);
    }

    /**
     * 20230418 wkz 获取第一个步骤
     *
     * @param flagId 标识id
     * @return {@link GwjConfStep}
     */
    @Override
    public GwjConfStep getFirstStep(Integer flagId) {
        List<GwjConfStep> gwjConfSteps = gcStepMapper.selectGwjConfStepIdListByBizFlagId(flagId);
        return gwjConfSteps.get(0);
    }

    /**
     * 获取步骤信息
     *
     * @param stepId
     * @return 业务步骤
     */
    @Override
    public GwjConfStep selectByConfStepId(Long stepId) {
        return gcStepMapper.selectByGwjConfStepId(stepId);
    }

    /* 
     * 判定当前步骤是否是最后一步
     */
    @Override
    public JSONObject checkNextStepFinish(Integer flagId, Long stepId) {
        JSONObject json = new JSONObject();
        Boolean finishStatus = false;
        GwjConfStep nextStep = null;
        // 1获取步骤列表
        List<GwjConfStep> gwjConfStepList = gcStepMapper.selectGwjConfStepIdListByBizFlagId(flagId);
        // key相同时保留新数据
        Map<Long, GwjConfStep> confStepsMap = gwjConfStepList.stream().collect(Collectors.toMap(GwjConfStep::getStepId, Function.identity(), (key1, key2) -> key2));
        GwjConfStep rGwjConfStep = confStepsMap.get(stepId);
        if (StringUtils.isNull(rGwjConfStep)) {
            throw new ServiceException("checkFinishStep未获取到对应步骤信息！");
        }
        // 如果当前编号与最后一个编号一致，默认判定是最后一步
        // 获取最后一步
        GwjConfStep finishGwjConfStep = gwjConfStepList.get(gwjConfStepList.size() - 1);
        if (stepId == finishGwjConfStep.getStepId() && StringUtils.inStringIgnoreCase(finishGwjConfStep.getName(), "办结", "完结", "案例回顾")) {
            // 与最后一步一致也当最后一步处理
            finishStatus = true;
            nextStep = rGwjConfStep;
        } else {
            // 否则获取对应的下一个步骤信息
            Integer sort = rGwjConfStep.getSort();
            // // 如果序列小于当前最大值
            // if (sort < (gwjConfStepList.size() - 1)) {
            // // 获取对应序列下的对象(1,2,3,4对应集合0,1,2,3 序列2的下一位就是集合的下标2)
            // nextStep = gwjConfStepList.get(sort);
            // // 如果下一步是办结则进行标注
            // if (nextStep.getStepId() == finishGwjConfStep.getStepId()) {
            // finishStatus = true;
            // }

            // 如果序列大于集合下标，则警告
            if (sort > (gwjConfStepList.size() - 1)) {
                throw new ServiceException("当前步骤序列不符合标准，请重新设置！");
            }
            // 获取对应序列下的对象(1,2,3,4对应集合0,1,2,3 序列2的下一位就是集合的下标2)
            // 获取步骤下一步
            nextStep = gwjConfStepList.get(sort);
            // 如果下一步是办结则进行标注
            if (nextStep.getStepId() == finishGwjConfStep.getStepId() && StringUtils.inStringIgnoreCase(finishGwjConfStep.getName(), "办结", "完结", "案例回顾")) {
                finishStatus = true;
            }
            // }
        }
        json.put("finishStatus", finishStatus);
        json.put("nextStep", nextStep);
        return json;
    }

}
